﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MySql.Data;
using MySql.Data.MySqlClient;
using System.Text.RegularExpressions;
using System.IO.Ports;

namespace Exp5
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private int current = 0;
        private string ConnString = @"server=localhost;User Id=root;password=123456;database=text;Character Set=gbk";
        private MySqlConnection conn;
        private MySqlCommand comm;

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {

                using (MySqlConnection conn = new MySqlConnection(ConnString))
                {

                    conn.Open();
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "操作数据库出错！", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //serialPort1.PortName = "COM2";
            try
            {
                //串口号配置
                string[] ports = System.IO.Ports.SerialPort.GetPortNames();//获取可用的串口号
                comboBox1.Items.AddRange(ports);    //添加串口号信息
                comboBox1.SelectedIndex = comboBox1.Items.Count > 0 ? 0 : 1;   //如果有数据显示第0个标签
                //serialPort1.Open();

                //默认配置
                comboBox2.Text = "115200";
                comboBox3.Text = "1";
                comboBox4.Text = "8";
                comboBox5.Text = "无";
                radioButton1.Checked = true;
                radioButton4.Checked = true;
            }
            catch
            {
                MessageBox.Show("串口未打开");
                this.Close();
            }

        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            int len = serialPort1.BytesToRead;//获取可以读取的字节数
            byte[] buff = new byte[len];//创建缓存数据数组
            serialPort1.Read(buff, 0, len);//把数据读取到buff数组

            string str = Encoding.Default.GetString(buff);//Byte值根据ASCII码表转为 String

            if (len == 0)
                return;

            Invoke((new Action(() =>
            {//C# 3.0以后代替委托的新方法
                //接收框数据显示
                if (radioButton1.Checked == true)   //字符串格式显示
                {
                    txGet.AppendText(str);//对话框追加显示数据
                }
                else if (radioButton2.Checked == true)      //16进制显示
                {
                    txGet.AppendText(byteToHexStr(buff));
                }
                //波形显示
                if (buff[0] == 0x66 && buff[buff.Length - 1] == 0x66)//检查帧头帧尾
                {
                    //清空Chart控件
                    chart1.Series[0].Points.Clear();

                    //恢复并显示波形
                    float fs = BitConverter.ToSingle(buff, 1);
                    float k = BitConverter.ToSingle(buff, 1 + 4);
                    float bias = BitConverter.ToSingle(buff, 1 + 4 * 2);
                    int N = BitConverter.ToInt32(buff, 1 + 4 * 3);
                    float[] U = new float[N];
                    for (int i = 0; i < N; i++)
                    {
                        ushort Ui_ushort = BitConverter.ToUInt16(buff, 1 + 4 * 3 + 4 + 2 * i);
                        U[i] = Ui_ushort * k - bias;
                        chart1.Series[0].Points.AddXY(i / fs, U[i]);
                    }

                    try
                    {
                        //存储数据
                        conn = new MySqlConnection(ConnString);
                        conn.Open(); //打开数据库连接
                        comm = new MySqlCommand();
                        comm.Connection = conn;
                        comm.CommandText = "INSERT INTO wave(wavedata,wavetime) VALUES (@blobdata,NOW())";
                        comm.Parameters.Clear();
                        comm.Parameters.AddWithValue(@"blobdata", buff);
                        comm.ExecuteNonQuery();

                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "操作数据库出错！", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        this.Close();
                    }
                    finally
                    {
                        conn.Close();// 关闭数据库连接
                    }
                }

            })));
        }
        /// <字节数组转16进制字符串>
        /// <param name="bytes"></param>
        /// <returns> String 16进制显示形式</returns>
        public static string byteToHexStr(byte[] bytes)
        {
            string returnStr = "";
            try
            {
                if (bytes != null)
                {
                    for (int i = 0; i < bytes.Length; i++)
                    {
                        returnStr += bytes[i].ToString("X2");
                        returnStr += " ";//两个16进制用空格隔开,方便看数据
                    }
                }
                return returnStr;
            }
            catch (Exception)
            {
                return returnStr;
            }
        }

        private void but_open_Click(object sender, EventArgs e)
        {
            if (but_open.Text == "打开串口")
            {
                try
                {
                    serialPort1.PortName = comboBox1.Text;   //获取串口号
                    serialPort1.BaudRate = int.Parse(comboBox2.Text);
                    serialPort1.DataBits = int.Parse(comboBox4.Text);
                    //设置停止位
                    if (comboBox3.Text == "0") { serialPort1.StopBits = StopBits.None; }
                    else if (comboBox3.Text == "1") { serialPort1.StopBits = StopBits.One; }
                    else if (comboBox3.Text == " 1.5") { serialPort1.StopBits = StopBits.OnePointFive; }
                    else if (comboBox3.Text == "2") { serialPort1.StopBits = StopBits.Two; }
                    //设置奇偶校验
                    if (comboBox5.Text == "无") { serialPort1.Parity = Parity.None; }
                    else if (comboBox5.Text == "奇校验") { serialPort1.Parity = Parity.Odd; }
                    else if (comboBox5.Text == "偶校验") { serialPort1.Parity = Parity.Even; }

                    serialPort1.Open();//打开串口
                    but_open.Text = "关闭串口";
                }
                catch (Exception err)
                {
                    MessageBox.Show("打开失败" + err.ToString(), "提示");
                }
            }
            else
            {
                try
                {
                    serialPort1.Close();
                }
                catch (Exception) { }
                but_open.Text = "打开串口";
            }
        }

        private void but_send_Click(object sender, EventArgs e)
        {
            String Str = textBox2.Text.ToString();//获取发送文本框里面的数据
            try
            {
                if (Str.Length > 0)
                {
                    if (radioButton4.Checked == true)   //字符串格式发送
                    {
                        serialPort1.Write(Str);//串口发送数据
                    }
                    else if (radioButton3.Checked == true)   //16进制发送
                    {
                        byte[] byt = strToToHexByte(Str);
                        serialPort1.Write(byt, 0, byt.Length);
                    }
                }
            }
            catch (Exception) { }
        }

        //字符串转化成16
        /// <字符串转16进制格式,不够自动前面补零>
        /// 
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        /// 
        /*010203040506 (偶数个数据)
        则01 ,02 ,03 ,04 ,05 ,06 分别作为16进制
        如果文本框中的字符个数是奇数个
        1115268
        则默认先把前面每隔两个作为一个16进制数
        最后一个数前面补零
        0x11,0x15,0x26,0x08*/
        private static byte[] strToToHexByte(String hexString)
        {
            int i;
            hexString = hexString.Replace(" ", "");//清除空格
            if ((hexString.Length % 2) != 0)//奇数个
            {
                byte[] returnBytes = new byte[(hexString.Length + 1) / 2];
                try
                {
                    for (i = 0; i < (hexString.Length - 1) / 2; i++)
                    {
                        returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
                    }
                    returnBytes[returnBytes.Length - 1] = Convert.ToByte(hexString.Substring(hexString.Length - 1, 1).PadLeft(2, '0'), 16);
                }
                catch
                {
                    MessageBox.Show("含有非16进制字符", "提示");
                    return null;
                }
                return returnBytes;
            }
            else
            {
                byte[] returnBytes = new byte[(hexString.Length) / 2];
                try
                {
                    for (i = 0; i < returnBytes.Length; i++)
                    {
                        returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
                    }
                }
                catch
                {
                    MessageBox.Show("含有非16进制字符", "提示");
                    return null;
                }
                return returnBytes;
            }
        }


        private void but_clc_Click(object sender, EventArgs e)
        {
            textBox2.Clear();   //清空发送框
        }


        //历史数据查看
        private void but_check_Click(object sender, EventArgs e)
        {
            int FileSize = 0;
            string sql = String.Format("SELECT * FROM wave WHERE waveID='{0}'",current);//SQL语句
            using (MySqlConnection conn = new MySqlConnection(ConnString))
            {
                conn.Open();
                MySqlCommand comm = new MySqlCommand(sql, conn); //创建 Command 对象
                MySqlDataReader reader = comm.ExecuteReader();
                if (reader.Read())  //读取数据行
                {


                    //text_time.Text = reader.GetString(2);
                    //读取blob类型的字段
                    //long len = reader.GetBytes(3, 0, null, 0, 0);//3为blob字段的索引（索引从0开始算）
                    long len = reader.GetBytes(reader.GetOrdinal("wavedata"), 0, null, 0, 0);
                    byte[] buff = new byte[len];
                    reader.GetBytes(reader.GetOrdinal("wavedata"), 0, buff, 0, (int)len);
                    string content = System.Text.Encoding.UTF8.GetString(buff, 0, buff.Length);

                    //text_time.Text += content;
                    //FileSize = Convert.ToInt32(reader.GetUInt32(reader.GetOrdinal("date_size")));
                    //byte[] buff = new byte[FileSize];//创建缓存数据数组
                    //reader.GetBytes(reader.GetOrdinal("wavedate"), 0, buff, 0, (int)FileSize);//把数据读取到buff数组
                    //string str = Encoding.Default.GetString(buff);//Byte值根据ASCII码表转为 String

                    if (FileSize == 0)
                        return;

                    //创建子进程
                    Invoke((new Action(() =>
                    {//C# 3.0以后代替委托的新方法
                        //波形显示
                        if (buff[0] == 0x66 && buff[buff.Length - 1] == 0x66)//检查帧头帧尾
                        {
                            //清空Chart控件
                            chart1.Series[0].Points.Clear();

                            //恢复并显示波形
                            float fs = BitConverter.ToSingle(buff, 1);
                            float k = BitConverter.ToSingle(buff, 1 + 4);
                            float bias = BitConverter.ToSingle(buff, 1 + 4 * 2);
                            int N = BitConverter.ToInt32(buff, 1 + 4 * 3);
                            float[] U = new float[N];
                            for (int i = 0; i < N; i++)
                            {
                                ushort Ui_ushort = BitConverter.ToUInt16(buff, 1 + 4 * 3 + 4 + 2 * i);
                                U[i] = Ui_ushort * k - bias;
                                chart1.Series[0].Points.AddXY(i / fs, U[i]);
                            }
                        }


                    })));

                }
            }
        }

        //历史数据查看
        private void showdate()
        {
            dataGridView1.Columns.Clear();
            // 自动调整行高度
            dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
            // 添加三列
            for (int i = 0; i < 3; i++)
            {
                dataGridView1.Columns.Add(new DataGridViewTextBoxColumn());
                dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            }
            // 三列标题
            dataGridView1.Columns[0].HeaderText = "waveID";
            dataGridView1.Columns[1].HeaderText = "wavedata";
            dataGridView1.Columns[2].HeaderText = "wavetime";
            string sql = String.Format("SELECT * FROM wave");//SQL语句
            using (MySqlConnection conn = new MySqlConnection(ConnString))
            {
                conn.Open();
                MySqlCommand comm = new MySqlCommand(sql, conn); //创建 Command 对象
                MySqlDataReader reader = comm.ExecuteReader();
                int numList = 0;
                if (reader.Read())  //读取数据行
                {
                    try
                    {
                        int index = this.dataGridView1.Rows.Add();
                        this.dataGridView1.Rows[index].Cells[0].Value = reader[0].ToString();
                        this.dataGridView1.Rows[index].Cells[1].Value = System.Text.Encoding.Default.GetBytes(reader[1].ToString());
                        this.dataGridView1.Rows[index].Cells[2].Value = reader[2].ToString();
                        numList += 1;
                    }
                    catch (Exception err)
                    {
                        MessageBox.Show("失败" + err.ToString(), "提示");
                    }

                }

            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            current++;
            showdate();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            current--;
            showdate();
        }









    }
}
